#include"ThreadCache.h"
#include"CentralCache.h"


// 申请内存对象
void* ThreadCache::Allocate(size_t size)
{
    assert(size <= MAX_BYTES);

    size_t index = SizeClass::Index(size);
    size_t alignSize = SizeClass::RoundUp(size);

    if(!_freeLists[index].Empty())
    {
        return _freeLists[index].Pop();
    }
    else
    {
        return FetchFromCentralCache(index, alignSize);
    }
}


// 从central cache中获取内存对象
void* ThreadCache::FetchFromCentralCache(size_t index, size_t size)
{
    // 慢开始反馈调节算法
    // 1. 一次不会向central cache中申请太多的内存对象, 可能用不完浪费
    // 2. 如果不断有size大小的内存需求, 那么batchNum将会不断变大直至上限
    // 3. size越大, 一次批量申请内存对象就越少
    // 4. size越小, 一次批量申请内存对象就越多
    size_t batchNum = std::min(_freeLists[index].MaxSize(), SizeClass::NumMoveSize(size));
    if(batchNum == _freeLists[index].MaxSize())
    {
        _freeLists[index].MaxSize() += 1;
    }

    void* start = nullptr;
    void* end = nullptr;
    size_t actualNum = CentralCache::GetInstance()->FetchRangeObject(start, end, batchNum, size);
    assert(actualNum > 0);

    if(actualNum == 1)
    {
        assert(start == end);
        return start;
    }
    else
    {
        _freeLists[index].PushRange(NextObj(start), end);
        return start;
    }
}